<?php

namespace App\Services\User;

use App\Actions\MessageAction;
use App\Actions\PaycallAction;
use App\Constants\CodeData;
use App\Dao\AnchorDao;
use App\Dao\AnchorSortLogDao;
use App\Dao\AppUpgradeDao;
use App\Dao\AutoReplyDao;
use App\Dao\GiftDao;
use App\Dao\GreetMasterDao;
use App\Dao\UserBlacklistDao;
use App\Dao\UserDao;
use App\Dao\UserTeaseDao;
use App\Exception\MessageException;
use App\Model\FateConfig;
use App\Model\FateConfigUser;
use App\Model\IncomeExpense;
use App\Model\User;
use App\Model\UserChatLimit;
use App\Services\Mission\MissionQueue;
use App\Services\PushMessageService;
use App\Utils\FunUtil;
use App\Utils\RedisClient;
use Hyperf\DbConnection\Db;

class ChatService
{
    /**
     * Note - 打招呼
     * DateTime 2024/8/14 14:09
     * User Admin
     */
    public function tease($userInfo, $params)
    {
        $uid = $userInfo['id'];
        $user_id = $params['user_id'] ?? '';
        $master_ids = $params['master_ids'] ?? '';
        $isBatch = !$master_ids;
        // 禁言判断
        if (FunUtil::gagUserChat($uid)) {
            throw new MessageException("账号异常正在风险审核中，审核通过才可以使用该功能，请耐心等候。", CodeData::NEED_TIPS);
        }
        if ($userInfo['sex'] == 2 && $userInfo['nickname'] == $userInfo['id']) {
            throw new MessageException("您的昵称已被重置，请修改昵称后再试!", CodeData::NEED_TIPS);
        }
        if ($userInfo['sex'] == 2 && (empty($userInfo['head_image']) || str_contains($userInfo['head_image'], 'default/headimg/woman'))) {
            throw new MessageException("请重新上传头像!", CodeData::NEED_TIPS);
        }
        if ($userInfo['isdel'] == 1) {
            throw new MessageException("该账户已注销！", CodeData::NEED_TIPS);
        }


        // 判断oppo、vivo渠道不能被搭讪
        $exists = User::query()->where('id', $user_id)->where(function ($query) {
            $query->whereIn('channel', ['xy_oppo', 'xy_vivo', 'xy_bd'])->orWhereRaw("json_extract(ext2, '$.channel') in ('xy_oppo', 'xy_vivo', 'xy_bd')");
        })->exists();
        if ($exists) {
            // 特殊渠道用户，不可搭讪
            return formatData(['result' => 2, 'rs' => true], 200, CodeData::NEED_TIPS);
        }

        // 主播选择模板，一键搭讪
        if ($userInfo['sex'] == 2 && $master_ids && count(explode(",", $master_ids)) > 0) {
            $this->teaseToUserForMasterId($userInfo, $params);
        }
        $user_ids = explode(",", $user_id);
        if ($userInfo['sex'] == 2) {
            // 主播跟用户搭讪
            if (count($user_ids) > 1) {
                return $this->teaseToUserBatch($userInfo, $params, $user_ids);
            }
            return $this->teaseToUser($userInfo, $params, $isBatch);
        } else {
            // 判断男用户是否是风险用户
            $userLimit = UserChatLimit::query()->where('uid', $uid)->first();
            if (!empty($userLimit)) {
                // 记录用户撩他
                UserTeaseDao::getInstance()->recordTease($uid, $user_id);
                return formatData(['result' => 1, 'rs' => true], 200, CodeData::SUCCESS);
            }
            // 男用户跟主播搭讪
            if (count($user_ids) > 1) {
                // 男用户批量跟主播搭讪
                return $this->teaseToAnchorBatch($userInfo, $params, $user_ids);
            } else {
                // 男用户跟主播搭讪
                return $this->teaseToAnchorSingle($userInfo, $params);
            }
        }

    }


    /**
     * Note - 主播批量随机搭讪，选择了模板
     * DateTime 2024/8/14 18:58
     * User Admin
     * @param $userInfo
     * @param $params
     * @return array
     */
    public function teaseToUserForMasterId($userInfo, $params)
    {
        $uid = $userInfo['id'];
        $language = $params['language'] ?? 'en';
        $master_ids = $params['master_ids'] ?? '';
        $isBatch = !$master_ids;

        $redis = RedisClient::getInstance();
        $tag = $redis->get("anchor_tease_tag_" . $uid);
        if ($tag) {
            $remain = $redis->ttl("anchor_tease_tag_" . $uid);
            // throw new MessageException("点击过快，休息下，$remain 秒后再试试");
            // 点击过快
            return formatData(['result' => 3, 'over_time' => time() + $remain], 200, CodeData::NEED_TIPS);
        }

        [$batchClickLimit, $limit] = $this->getTeaseLimit($userInfo);
        $count = $redis->get("anchor_tease_count_one_click:{$uid}") ?: 0;
        if ($count >= $batchClickLimit) {
            // Tool::JSON(\CodeData::NEED_TIPS, ['result' => 0], "可用次数不足！");
            // 可用次数不足
            return formatData(['result' => 4], 200, CodeData::NEED_TIPS, '可用次数不足！');
        }


        $greets = GreetMasterDao::getInstance()->getGreets($uid, explode(',', $master_ids));
        // 打招呼模板数据
        if (!empty($greets)) {
            $messageAction = new MessageAction();
            $user_ids = UserDao::getInstance()->getBitchUserIds($uid);
            if (empty($user_ids)) {
                // 小哥哥正在赶来的路上，请稍后再发送
                return formatData(['result' => 5], 200, CodeData::NEED_TIPS, '小哥哥正在赶来的路上，请稍后再发送');
            }
            $over_time = strtotime(date("Y-m-d") . " 23:59:59") - time();
            $redis->set("anchor_tease_count_one_click:{$uid}", $count + 1, $over_time);
            foreach ($user_ids as $key => $id) {
                $id = $id['id'];
                $greet = $greets[array_rand($greets)];
                // 发送免费礼物
                GiftDao::getInstance()->sendFreeGift($uid, $id, 176, $language);

                if ($greet['audio_url']) {
                    // $rs = $wyyClient->putSendMsgQueue($uid, $id, $greet["audio_url"], 2, 5, $greet["audio_len"]);
                    $rs = $messageAction->sendAccostMsg($uid, $id, $greet["audio_url"], 2, 5, $greet["audio_len"]);

                }

                if ($greet['image_url']) {
                    // $rs = $wyyClient->putSendMsgQueue($uid, $id, $greet["image_url"], 3, 5);
                    $rs = $messageAction->sendAccostMsg($uid, $id, $greet["image_url"], 3, 5);
                }

                if ($greet["text"]) {
                    // $rs = $wyyClient->putSendMsgQueue($uid, $id, $greet["text"], 1, 5);
                    $rs = $messageAction->sendAccostMsg($uid, $id, $greet["text"], 1, 5);
                }
                // 记录用户撩他
                UserTeaseDao::getInstance()->recordTease($uid, $id, $isBatch ? 1 : 2);

            }
        }
        $redis->setex("anchor_tease_tag_" . $uid, 60, 1);
        return formatData(['result' => 1, 'rs' => $rs ?? false, 'uids' => $user_ids ?? [], 'over_time' => time() + 60], 200, CodeData::SUCCESS);
    }


    /**
     * Note - 跟主播搭讪，批量
     * DateTime 2024/8/14 17:13
     * User Admin
     */
    public function teaseToAnchorBatch($userInfo, $params, $user_ids)
    {
        $uid = $userInfo['id'];
        $sex = $userInfo['sex'];
        $language = $params['language'];
        $flag = 0;
        foreach ($user_ids as $userId) {
            // 发送免费礼物
            GiftDao::getInstance()->sendFreeGift($uid, $userId, 176, $language);
            $text_price = 1;
            if (User::query()->where('id', $uid)->sum(Db::raw("gift_count+chat_count+recharge_send_count+sys_send_count")) < $text_price) {
                continue;
            }
            [$script_id, $content] = AutoReplyDao::getInstance()->getReplyContentWithId($userId, 2, $language);

            // $wyyClient = $wyyClient ?? new WyyClient();
            // $rs = $wyyClient->putSendMsgQueue($uid, $userId, $content, 1, 5);
            $rs = PushMessageService::putYunXinSendMsgQueue($uid, $userId, $content, 1, 5);
            if (!$rs) {
                continue;
            }
            if (CHARGE_CALL_VERSION) {
                //扣除男用户金币，给女用户加积分
                $res = (new PaycallAction())->payForMessage($uid, $userId, $text_price, SINGLE_MESSAGE_RATE);
            }
            $flag = 1;

            // 记录用户撩他
            UserTeaseDao::getInstance()->recordTease($uid, $userId, 1);
        }
        if ($flag) {
            MissionQueue::tease($uid, $sex);
            // $cb['result'] = 1;
            // $cb['rs'] = 2;
            // $cb['uids'] = $user_ids;
            // Tool::JSON(\CodeData::SUCCESS, $cb, 'success');
            return formatData(['result' => 1, 'rs' => 2, 'uids' => $user_ids], 200, CodeData::SUCCESS);
        }
    }


    /**
     * Note - 跟主播搭讪，手动
     * DateTime 2024/8/14 18:24
     * User Admin
     * @param $userInfo
     * @param $params
     * @return array
     */
    public function teaseToAnchorSingle($userInfo, $params)
    {
        $uid = $userInfo['id'];
        $user_id = $params['user_id'];
        $language = $params['language'];
        $from = $params['from'];
        $version_code = $params['version_code'];
        $channel = $params['channel'];
        $rs = false;
        [$script_id, $content] = AutoReplyDao::getInstance()->getReplyContentWithId($user_id, 2, $language);
        //发消息收费
        $appupgradeModel = new AppUpgradeDao();
        if (!$appupgradeModel->isHideMaleChatCost($from, $version_code, $channel, FunUtil::getClientIp(), $uid)) {
            //判断用户剩余金币
            // $text_price=(new AnchorModel())->getValue($user_id,"greet_price");
            if (CHARGE_CALL_VERSION) {
                $text_price = 1;
                if (User::query()->where('id', $uid)->sum(Db::raw("gift_count+chat_count+recharge_send_count+sys_send_count")) < $text_price) {
                    throw new MessageException("您的金币余额不足");
                }
            }
            // 发送免费礼物
            GiftDao::getInstance()->sendFreeGift($uid, $user_id, 176, $language);
            $messageAction = new MessageAction();
            $rs = $messageAction->sendAccostMsg($uid, $user_id, $content, 1, 5);
            if (!$rs) {
                throw new MessageException("发送失败！");
            }

            if (CHARGE_CALL_VERSION) {
                //扣除男用户金币，给女用户加积分
                $res = (new PaycallAction())->payForMessage($uid, $user_id, $text_price, SINGLE_MESSAGE_RATE);
            }
        }

        // 记录用户撩他
        UserTeaseDao::getInstance()->recordTease($uid, $user_id, 2);
        MissionQueue::tease($uid, $userInfo['sex']);
        return formatData(['result' => 1, 'rs' => $rs], 200, CodeData::SUCCESS);
    }


    /**
     * Note - 跟男用户搭讪
     * DateTime 2024/8/14 17:15
     * User Admin
     */
    public function teaseToUser($userInfo, $params, $isBatch)
    {
        $uid = $userInfo['id'];
        $user_id = $params['user_id'];
        $language = $params['language'];
        $master_id = $params['master_id'] ?? 0;
        $redis = RedisClient::getInstance();
        if ($master_id) {
            $vv = $redis->get("anchor_tease:{$uid}_{$master_id}");
            if ($vv) {
                // Tool::JSON(\CodeData::NEED_TIPS, ['result' => 0], "请不要重复点击！");
                return formatData(['result' => 0], 200, "请不要重复点击！");
            }
            $redis->set("anchor_tease:{$uid}_{$master_id}", $master_id, 5);
        } else {
            // 女用户每天搭讪数量限制
            [$batchClickLimit, $limit] = $this->getTeaseLimit($userInfo);
            $count = $redis->get("anchor_tease_count:{$uid}") ?: 0;
            if ($count >= $limit) {
                // Tool::JSON(\CodeData::NEED_TIPS, ['result' => 0], "可用次数不足！");
                return formatData(['result' => 0], 200, "可用次数不足！");
            }

            $greet_count = $limit - $count - 1;
            $cb['greet_count'] = $greet_count;
        }


        // 判断是否是风险用户
        // $userLimit = $userModel->find("id", "uid=? and status=1", [$user_id], '', 'tb_user_chat_limit');
        $userLimit = UserChatLimit::query()->where('uid', $user_id)->where('status', 1)->first();
        // 判断今日已经是否搭讪过
        $isTease = UserDao::getInstance()->readTease($user_id, $uid);
        if (!empty($isTease) || !empty($userLimit)) {
            UserTeaseDao::getInstance()->recordTease($uid, $user_id, $isBatch ? 1 : 2);
            return formatData(['result' => 1, 'rs' => true], 200, CodeData::SUCCESS);
        }

        if (UserBlacklistDao::getInstance()->inBlackList($uid, $user_id)) {
            throw new \Exception("你已拉黑对方或对方已拉黑你");
        }

        //登陆10分钟内的男用户不被搭讪
        // $login_time = $userModel->value($user_id, 'login_time');
        $login_time = User::query()->where('id', $user_id)->value('login_time');
        $sync_sender = ($login_time >= time() - 600) ? 3 : 1;

        if ($sync_sender == 3) {
            $cb['result'] = 1;
            $cb['rs'] = true;
            return formatData($cb, 200, CodeData::SUCCESS);
        }

        // 发送免费礼物
        GiftDao::getInstance()->sendFreeGift($uid, $user_id, 176, $language);

        $greet = GreetMasterDao::getInstance()->getRandOne($uid, intval($master_id));
        if (!empty($greet)) {
            // $wyyClient = $wyyClient ?? new WyyClient();
            $messageAction = $messageAction ?? new MessageAction();

            if ($greet['audio_url']) {
                // $rs = $wyyClient->putSendMsgQueue($uid, $user_id, $greet["audio_url"], 2, 5, $greet["audio_len"]);
                $rs = $messageAction->sendAccostMsg($uid, $user_id, $greet["audio_url"], 2, 5, $greet["audio_len"], 0, 0, $sync_sender);
            }

            if ($greet['image_url']) {
                // $rs = $wyyClient->putSendMsgQueue($uid, $user_id, $greet["image_url"], 3, 5);
                $rs = $messageAction->sendAccostMsg($uid, $user_id, $greet["image_url"], 3, 5, 0, 0, 0, $sync_sender);
            }
            if ($greet["text"]) {
                // $rs = $wyyClient->putSendMsgQueue($uid, $user_id, $greet["text"], 1, 5);
                $rs = $messageAction->sendAccostMsg($uid, $user_id, $greet["text"], 1, 5, 0, 0, 0, $sync_sender);
            }
            // 撩他记录主播排序分
            AnchorSortLogDao::record($uid, 8, 1);
        } else {
            // 没有设置模板自动调用系统预设招呼语
            $content = (new AutoReplyDao())->sendGreet(3, $language);
            if ($content) {
                $messageAction = $messageAction ?? new MessageAction();
                $rs = $messageAction->sendAccostMsg($uid, $user_id, $content, 1, 5, 0, 0, 0, $sync_sender);
            }
        }

        if (!$master_id) {
            $over_time = strtotime(date("Y-m-d") . " 23:59:59") - time();
            $redis->set("anchor_tease_count:{$uid}", $count + 1, $over_time);
            $greet_count = $limit - $count - 1;
            $cb['greet_count'] = $greet_count;
        }

        UserTeaseDao::getInstance()->recordTease($uid, $user_id, $isBatch ? 1 : 2);
        MissionQueue::tease($uid, $userInfo['sex']);
        $cb['result'] = 1;
        $cb['rs'] = $rs ?? false;
        return formatData($cb, 200, CodeData::SUCCESS);
    }


    /**
     * Note - 跟男用户批量搭讪，没有选择模板
     * DateTime 2024/8/14 18:51
     * User Admin
     * @param $userInfo
     * @param $params
     * @param array $user_ids
     * @return array
     */
    private function teaseToUserBatch($userInfo, $params, array $user_ids)
    {
        $uid = $userInfo['id'];
        $from = $params['from'];
        $version_code = $params['version_code'];
        $channel = $params['channel'];
        if ((new AppUpgradeDao())->isHideRobotChat($from, $version_code, $channel)) {
            foreach ($user_ids as $userId) {
                PushMessageService::putYunXinSendMsgQueue($uid, $userId, '你好！', 1, 5);
            }
            return formatData(['result' => 1, 'rs' => true], 200, CodeData::SUCCESS);
        }
        return formatData(['result' => 1, 'rs' => true], 200, CodeData::SUCCESS);

    }


    /**
     * Note - 搭讪数量限制
     * DateTime 2024/8/14 15:01
     * User Admin
     * @param $userInfo
     * @return array|int[]
     */
    public function getTeaseLimit($userInfo)
    {
        $limit = $batchClickLimit = 100000;
        $uid = $userInfo['id'];
        $sex = $userInfo['sex'];
        $pushLevel = $userInfo['push_level'];

        // 新用户，注册3天内
        if ((time() - $userInfo['register_time']) < 86400 * 3) {
            return [$batchClickLimit, $limit];
        }

        $flag = false;
        // 公会用户
        if (!empty($userInfo['guild_num'])) {
            // $sql = "SELECT config_value FROM tb_fate_config WHERE config_id='prior_guild'";
            // $prior_guild = $model->findOneField($sql, 'config_value');
            $prior_guild = FateConfig::query()->where('config_id', 'prior_guild')->value('config_value');
            if (str_contains($prior_guild, $userInfo['guild_num'])) {
                // $time = strtotime(date("Y-m-d", strtotime("-6 days")));
                $time = strtotime(date("Y-m-d")) - (6 * 86400);
                // $sql = "SELECT IFNULL(SUM(amount),0) amount FROM tb_income_expense WHERE uid=$uid AND type=1 AND sub_type IN (2,3,4,7) AND ctime>=$time";
                // $amount = $model->findOneField($sql, 'amount');
                $amount = IncomeExpense::query()->where('uid', $uid)
                    ->where('type', 1)
                    ->whereIn('sub_type', [2, 3, 4, 7])
                    ->where('ctime', '>=', $time)
                    ->sum('amount');
                if ($amount < 100) {
                    // 6天内收入小于100
                    $flag = true;
                    $batchClickLimit = $limit = 100;
                }
            }
        }

        if (!$flag) {
            // $sql = "SELECT batch_tease_limit,tease_limit FROM tb_fate_config_user WHERE sex=$sex AND level=$pushLevel";
            // $rs = $model->findOne($sql);
            $rs = FateConfigUser::query()->where('sex', $sex)
                ->where('level', $pushLevel)
                ->first();
            if (!empty($rs)) {
                $limit = $rs['tease_limit'];
                $batchClickLimit = $rs['batch_tease_limit'];
            }
        }

        return [$batchClickLimit, $limit];
    }


    /**
     * Note - 批量获取打招呼用户(今日缘分，只有男用户有)
     * DateTime 2024/8/15 10:17
     * User Admin
     * @return array
     */
    public function getBatchGreetUser(mixed $userInfo)
    {
        $uid = $userInfo['id'];
        if ($userInfo['sex'] == 2) {
            throw new MessageException("男用户才调用");
        }
        if ($userInfo['register_time_new'] > time() - 3 * 86400) {
            // Tool::JSON(\CodeData::SUCCESS, null, 'success');
            throw new MessageException("新用户不可匹配");
        }
        $users = AnchorDao::getInstance()->getBatchGreetAnchor($uid);
        if (empty($users)) {
            throw new MessageException("暂无符合条件的用户");
        }
        $cb['result'] = 1;
        $cb['rs'] = $users;
        // Tool::JSON(\CodeData::SUCCESS, $cb, 'success');
        return formatData($cb, 200, CodeData::SUCCESS);
    }


}